"""
KidsBuddy 1.0 用户数据仓库
提供用户数据的CRUD操作和持久化功能
"""

import json
import os
from datetime import datetime
from pathlib import Path
from typing import Dict, List, Optional, Any, Union
from loguru import logger

from ..models.user import Child, Parent, UserRole
from ..utils.validators import ValidationError
from ..utils.user_validators import validate_child_data, validate_parent_data


class UserRepository:
    """用户数据仓库"""
    
    def __init__(self, data_dir: Optional[str] = None):
        """
        初始化用户数据仓库
        
        Args:
            data_dir: 数据存储目录，默认为项目根目录下的data文件夹
        """
        if data_dir is None:
            # 获取项目根目录
            current_file = Path(__file__)
            project_root = current_file.parent.parent.parent
            data_dir = project_root / "data"
        
        self.data_dir = Path(data_dir)
        self.users_dir = self.data_dir / "users"
        self.children_dir = self.users_dir / "children"
        self.parents_dir = self.users_dir / "parents"
        
        # 确保目录存在
        self._ensure_directories()
        
        # 内存缓存
        self._children_cache: Dict[str, Child] = {}
        self._parents_cache: Dict[str, Parent] = {}
        self._cache_loaded = False
    
    def _ensure_directories(self):
        """确保所有必要的目录存在"""
        directories = [self.data_dir, self.users_dir, self.children_dir, self.parents_dir]
        for directory in directories:
            directory.mkdir(parents=True, exist_ok=True)
    
    def _load_cache(self):
        """加载所有用户数据到内存缓存"""
        if self._cache_loaded:
            return
        
        try:
            # 加载儿童用户
            for child_file in self.children_dir.glob("*.json"):
                try:
                    with open(child_file, 'r', encoding='utf-8') as f:
                        data = json.load(f)
                        child = Child.from_dict(data)
                        self._children_cache[child.id] = child
                except Exception as e:
                    logger.error(f"加载儿童用户文件失败 {child_file}: {e}")
            
            # 加载家长用户
            for parent_file in self.parents_dir.glob("*.json"):
                try:
                    with open(parent_file, 'r', encoding='utf-8') as f:
                        data = json.load(f)
                        parent = Parent.from_dict(data)
                        self._parents_cache[parent.id] = parent
                except Exception as e:
                    logger.error(f"加载家长用户文件失败 {parent_file}: {e}")
            
            self._cache_loaded = True
            logger.info(f"用户缓存加载完成: {len(self._children_cache)}个儿童, {len(self._parents_cache)}个家长")
            
        except Exception as e:
            logger.error(f"加载用户缓存失败: {e}")
    
    def _save_child_to_file(self, child: Child):
        """保存儿童用户到文件"""
        file_path = self.children_dir / f"{child.id}.json"
        try:
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(child.to_dict(), f, indent=2, ensure_ascii=False)
            logger.debug(f"儿童用户已保存: {child.id}")
        except Exception as e:
            logger.error(f"保存儿童用户失败 {child.id}: {e}")
            raise
    
    def _save_parent_to_file(self, parent: Parent):
        """保存家长用户到文件"""
        file_path = self.parents_dir / f"{parent.id}.json"
        try:
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(parent.to_dict(), f, indent=2, ensure_ascii=False)
            logger.debug(f"家长用户已保存: {parent.id}")
        except Exception as e:
            logger.error(f"保存家长用户失败 {parent.id}: {e}")
            raise
    
    # ==================== 儿童用户CRUD操作 ====================
    
    def create_child(self, child: Child) -> Child:
        """
        创建儿童用户
        
        Args:
            child: 儿童用户对象
            
        Returns:
            创建的儿童用户对象
            
        Raises:
            ValidationError: 验证失败
            ValueError: 用户ID已存在
        """
        self._load_cache()
        
        # 检查ID是否已存在
        if child.id in self._children_cache:
            raise ValueError(f"儿童用户ID已存在: {child.id}")
        
        # 验证用户数据
        child.validate()

        # 保存到文件和缓存
        child.created_at = datetime.now()
        child.update_timestamp()
        
        self._save_child_to_file(child)
        self._children_cache[child.id] = child
        
        logger.info(f"儿童用户创建成功: {child.id} - {child.name}")
        return child
    
    def get_child(self, child_id: str) -> Optional[Child]:
        """
        获取儿童用户
        
        Args:
            child_id: 儿童用户ID
            
        Returns:
            儿童用户对象，如果不存在则返回None
        """
        self._load_cache()
        return self._children_cache.get(child_id)
    
    def update_child(self, child: Child) -> Child:
        """
        更新儿童用户
        
        Args:
            child: 儿童用户对象
            
        Returns:
            更新后的儿童用户对象
            
        Raises:
            ValueError: 用户不存在
        """
        self._load_cache()
        
        if child.id not in self._children_cache:
            raise ValueError(f"儿童用户不存在: {child.id}")

        # 验证用户数据
        child.validate()

        # 更新时间戳
        child.update_timestamp()
        
        # 保存到文件和缓存
        self._save_child_to_file(child)
        self._children_cache[child.id] = child
        
        logger.info(f"儿童用户更新成功: {child.id} - {child.name}")
        return child
    
    def delete_child(self, child_id: str) -> bool:
        """
        删除儿童用户
        
        Args:
            child_id: 儿童用户ID
            
        Returns:
            是否删除成功
        """
        self._load_cache()
        
        if child_id not in self._children_cache:
            return False
        
        # 从文件系统删除
        file_path = self.children_dir / f"{child_id}.json"
        try:
            if file_path.exists():
                file_path.unlink()
            
            # 从缓存删除
            del self._children_cache[child_id]
            
            logger.info(f"儿童用户删除成功: {child_id}")
            return True
            
        except Exception as e:
            logger.error(f"删除儿童用户失败 {child_id}: {e}")
            return False
    
    def list_children(self, parent_id: Optional[str] = None, active_only: bool = True) -> List[Child]:
        """
        列出儿童用户
        
        Args:
            parent_id: 家长ID，如果指定则只返回该家长的子女
            active_only: 是否只返回活跃用户
            
        Returns:
            儿童用户列表
        """
        self._load_cache()
        
        children = list(self._children_cache.values())
        
        # 过滤条件
        if active_only:
            children = [child for child in children if child.is_active]
        
        if parent_id:
            children = [child for child in children if parent_id in child.parent_ids]
        
        # 按创建时间排序
        children.sort(key=lambda x: x.created_at, reverse=True)
        
        return children

    # ==================== 家长用户CRUD操作 ====================

    def create_parent(self, parent: Parent) -> Parent:
        """
        创建家长用户

        Args:
            parent: 家长用户对象

        Returns:
            创建的家长用户对象

        Raises:
            ValidationError: 验证失败
            ValueError: 用户ID或邮箱已存在
        """
        self._load_cache()

        # 检查ID是否已存在
        if parent.id in self._parents_cache:
            raise ValueError(f"家长用户ID已存在: {parent.id}")

        # 检查邮箱是否已存在
        for existing_parent in self._parents_cache.values():
            if existing_parent.email == parent.email and existing_parent.is_active:
                raise ValueError(f"邮箱已被使用: {parent.email}")

        # 验证用户数据
        parent.validate()

        # 保存到文件和缓存
        parent.created_at = datetime.now()
        parent.update_timestamp()

        self._save_parent_to_file(parent)
        self._parents_cache[parent.id] = parent

        logger.info(f"家长用户创建成功: {parent.id} - {parent.name}")
        return parent

    def get_parent(self, parent_id: str) -> Optional[Parent]:
        """
        获取家长用户

        Args:
            parent_id: 家长用户ID

        Returns:
            家长用户对象，如果不存在则返回None
        """
        self._load_cache()
        return self._parents_cache.get(parent_id)

    def get_parent_by_email(self, email: str) -> Optional[Parent]:
        """
        通过邮箱获取家长用户

        Args:
            email: 邮箱地址

        Returns:
            家长用户对象，如果不存在则返回None
        """
        self._load_cache()
        for parent in self._parents_cache.values():
            if parent.email.lower() == email.lower() and parent.is_active:
                return parent
        return None

    def update_parent(self, parent: Parent) -> Parent:
        """
        更新家长用户

        Args:
            parent: 家长用户对象

        Returns:
            更新后的家长用户对象

        Raises:
            ValueError: 用户不存在
        """
        self._load_cache()

        if parent.id not in self._parents_cache:
            raise ValueError(f"家长用户不存在: {parent.id}")

        # 验证用户数据
        parent.validate()

        # 更新时间戳
        parent.update_timestamp()

        # 保存到文件和缓存
        self._save_parent_to_file(parent)
        self._parents_cache[parent.id] = parent

        logger.info(f"家长用户更新成功: {parent.id} - {parent.name}")
        return parent

    def delete_parent(self, parent_id: str) -> bool:
        """
        删除家长用户

        Args:
            parent_id: 家长用户ID

        Returns:
            是否删除成功
        """
        self._load_cache()

        if parent_id not in self._parents_cache:
            return False

        # 从文件系统删除
        file_path = self.parents_dir / f"{parent_id}.json"
        try:
            if file_path.exists():
                file_path.unlink()

            # 从缓存删除
            del self._parents_cache[parent_id]

            logger.info(f"家长用户删除成功: {parent_id}")
            return True

        except Exception as e:
            logger.error(f"删除家长用户失败 {parent_id}: {e}")
            return False

    def list_parents(self, active_only: bool = True) -> List[Parent]:
        """
        列出家长用户

        Args:
            active_only: 是否只返回活跃用户

        Returns:
            家长用户列表
        """
        self._load_cache()

        parents = list(self._parents_cache.values())

        # 过滤条件
        if active_only:
            parents = [parent for parent in parents if parent.is_active]

        # 按创建时间排序
        parents.sort(key=lambda x: x.created_at, reverse=True)

        return parents

    # ==================== 关系管理操作 ====================

    def link_parent_child(self, parent_id: str, child_id: str, relationship: str = "parent") -> bool:
        """
        建立家长和儿童的关系

        Args:
            parent_id: 家长用户ID
            child_id: 儿童用户ID
            relationship: 关系类型

        Returns:
            是否建立成功
        """
        self._load_cache()

        parent = self.get_parent(parent_id)
        child = self.get_child(child_id)

        if not parent or not child:
            return False

        # 添加关系
        parent.add_child(child_id, relationship)
        if parent_id not in child.parent_ids:
            child.parent_ids.append(parent_id)
            child.update_timestamp()

        # 保存更新
        self._save_parent_to_file(parent)
        self._save_child_to_file(child)

        # 更新缓存
        self._parents_cache[parent_id] = parent
        self._children_cache[child_id] = child

        logger.info(f"建立家长-儿童关系: {parent_id} -> {child_id} ({relationship})")
        return True
